package com.ququ.syb.entrance.service;

import com.ququ.common.result.Result;
import com.ququ.common.result.ResultJson;
import com.ququ.common.utils.RegExpUtil;
import com.ququ.syb.common.constant.EncryptTypeConstant;
import com.ququ.syb.common.constant.PayChannelStatusConstant;
import com.ququ.syb.common.constant.PayOrderTypeConstant;
import com.ququ.syb.common.constant.ResultStatusConstant;
import com.ququ.syb.common.pojo.AccountInfo;
import com.ququ.syb.common.pojo.PayChannel;
import com.ququ.syb.common.pojo.PayOrder;
import com.ququ.syb.common.pojo.PayResult;
import com.ququ.syb.entrance.fegin.AccountBusinessFegin;
import com.ququ.syb.entrance.fegin.ChannelBusinessFegin;
import com.ququ.syb.entrance.fegin.PaymentBusinessFegin;
import com.ququ.syb.entrance.po.RequestData;
import com.ququ.syb.entrance.vo.SybResult;
import com.ququ.syb.entrance.vo.SybResultData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
public class PaymentService {

    @Autowired
    private PaymentBusinessFegin paymentBusinessFegin;
    @Autowired
    private AccountBusinessFegin accountBusinessFegin;
    @Autowired
    private ChannelBusinessFegin channelBusinessFegin;
    @Autowired
    private SecurityService securityService;


    public SybResult createPayOrder(RequestData<String> requestData){
        if (requestData.getEncryptType() != EncryptTypeConstant.AES)
            return new SybResult(-1,"加密方式不正确",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        Map<String,Object> dataMap = securityService.getParametersMap(requestData);
        String accountid = requestData.getAccountid();
        String appcode = requestData.getAppcode();
        if (!dataMap.containsKey("orderno") || dataMap.get("orderno")==null )
            return new SybResult(-1,"缺少商户订单号",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        String orderno = dataMap.get("orderno").toString();
        if (!dataMap.containsKey("amount") || dataMap.get("amount") == null)
            return new SybResult(-1,"缺少订单金额参数",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        Long amount = Long.parseLong(dataMap.get("amount").toString());
        if (!dataMap.containsKey("ordertype") || dataMap.get("ordertype") == null)
            return new SybResult(-1,"缺少订单类型参数",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        Integer ordertype = Integer.parseInt(dataMap.get("ordertype").toString());
        if (!dataMap.containsKey("title") || dataMap.get("title") == null)
            return new SybResult(-1,"缺少订单标题参数",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        String title = dataMap.get("title").toString();
        if (!dataMap.containsKey("callbackurl") || dataMap.get("callbackurl") == null)
            return new SybResult(-1,"缺少异步回调地址参数",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        String callbackurl = dataMap.get("callbackurl").toString();
        if (!dataMap.containsKey("paychannelid") || dataMap.get("paychannelid") == null)
            return new SybResult(-1,"缺少支付通道号参数",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        String paychannelid = dataMap.get("paychannelid").toString();
        Result<PayChannel> payChannelResult = channelBusinessFegin.getPayChannel(paychannelid,accountid,appcode);
        if (payChannelResult.getStatus() != ResultStatusConstant.SUCCESS || payChannelResult.getData().getStatus() != PayChannelStatusConstant.NORMAL)
            return new SybResult(-1,"支付通道不存在或无此通道访问权限或收款方未开通此通道",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        String payeeaccount = accountid;
        String desc = (dataMap.containsKey("desc") && dataMap.get("desc") != null)? dataMap.get("desc").toString() : title;
        String returnurl = (dataMap.containsKey("returnurl") && dataMap.get("returnurl") != null)? dataMap.get("returnurl").toString() : null;
        String withdrawcallbackurl = (dataMap.containsKey("withdrawcallbackurl") && dataMap.get("withdrawcallbackurl") != null)? dataMap.get("withdrawcallbackurl").toString() : null;
        String payaccountid = (dataMap.containsKey("payaccountid") && dataMap.get("payaccountid") != null)? dataMap.get("payaccountid").toString() : null;
        if (payaccountid == null){
            if (ordertype == PayOrderTypeConstant.COLLECTION)
                payaccountid = accountid;
            else
                return new SybResult(-1,"非代收订单必须传入付款方账户参数",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        }
        Result<AccountInfo> payAccount = accountBusinessFegin.getAccountInfo(payaccountid);
        if (payAccount.getStatus() != ResultStatusConstant.SUCCESS)
            return new SybResult(-1,"付款方账户不存在",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        Long paycommission = (dataMap.containsKey("paycommission") && dataMap.get("paycommission") != null)? Long.parseLong(dataMap.get("paycommission").toString()) : null;
        Long payeecommission = (dataMap.containsKey("payeecommission") && dataMap.get("payeecommission") != null)? Long.parseLong(dataMap.get("payeecommission").toString()) : null;
        Integer assureday = (dataMap.containsKey("assureday") && dataMap.get("assureday") != null)? Integer.parseInt(dataMap.get("assureday").toString()) : null;
        Integer timeout = (dataMap.containsKey("timeout") && dataMap.get("timeout") != null)? Integer.parseInt(dataMap.get("timeout").toString()) : null;
        String divideinfo = (dataMap.containsKey("divideinfo") && dataMap.get("divideinfo") != null)? dataMap.get("divideinfo").toString() : null;
        if (ordertype == PayOrderTypeConstant.ASSURE && assureday == null)
            assureday = 7;      //担保订单担保期默认为7天
        if (divideinfo != null && !RegExpUtil.isJson(divideinfo))
            return new SybResult(-1,"分账信息格式不正确",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        //调用订单业务模块接口创建订单
        Result<PayOrder> payOrderResult = paymentBusinessFegin.createPayOrder(orderno,
                amount,
                ordertype,
                title,
                desc,
                returnurl,
                callbackurl,
                withdrawcallbackurl,
                payaccountid,
                payeeaccount,
                paycommission,
                payeecommission,
                appcode,
                paychannelid,
                assureday,
                timeout,
                divideinfo);
        if (payOrderResult.getStatus() == ResultStatusConstant.SUCCESS)
            return securityService.buildSybResult(payOrderResult.getData(),requestData);
        else
            return new SybResult(-1,payOrderResult.getMsg(),securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
    }


    public SybResult paymentOrPaySms(RequestData<String> requestData){
        if (requestData.getEncryptType() != EncryptTypeConstant.AES)
            return new SybResult(-1,"加密方式不正确",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        Map<String,Object> dataMap = securityService.getParametersMap(requestData);
        String accountid = requestData.getAccountid();
        String appcode = requestData.getAppcode();
        if (!dataMap.containsKey("tradenum") || dataMap.get("tradenum")==null )
            return new SybResult(-1,"缺少支付订单流水号",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        String tradenum = dataMap.get("tradenum").toString();
        String name = (dataMap.containsKey("name") && dataMap.get("name") != null)? dataMap.get("name").toString() : null;
        name = (name==null && dataMap.containsKey("bankaccountname") && dataMap.get("bankaccountname") != null)? dataMap.get("bankaccountname").toString() : name;
        String bankcardno = (dataMap.containsKey("bankcardno") && dataMap.get("bankcardno") != null)? dataMap.get("bankcardno").toString() : null;
        bankcardno = (bankcardno==null && dataMap.containsKey("bankaccountno") && dataMap.get("bankaccountno") != null)? dataMap.get("bankaccountno").toString() : bankcardno;
        String mobile = (dataMap.containsKey("mobile") && dataMap.get("mobile") != null)? dataMap.get("mobile").toString() : null;
        mobile = (mobile==null && dataMap.containsKey("cardholdermobile") && dataMap.get("cardholdermobile") != null)? dataMap.get("cardholdermobile").toString() : mobile;
        String idcardno = (dataMap.containsKey("idcardno") && dataMap.get("idcardno") != null)? dataMap.get("idcardno").toString() : null;
        idcardno = (idcardno == null && dataMap.containsKey("cardholderidcard") && dataMap.get("cardholderidcard") != null)? dataMap.get("cardholderidcard").toString() : idcardno;
        String expirydate = (dataMap.containsKey("expirydate") && dataMap.get("expirydate") != null)? dataMap.get("expirydate").toString() : null;
        String cvv2 = (dataMap.containsKey("cvv2") && dataMap.get("cvv2") != null)? dataMap.get("cvv2").toString() : null;
        String authcode = (dataMap.containsKey("authcode") && dataMap.get("authcode") != null)? dataMap.get("authcode").toString() : null;
        String openid = (dataMap.containsKey("openid") && dataMap.get("openid") != null)? dataMap.get("openid").toString() : null;
        String userip = (dataMap.containsKey("userip") && dataMap.get("userip") != null)? dataMap.get("userip").toString() : null;
        String buyerid = (dataMap.containsKey("buyerid") && dataMap.get("buyerid") != null)? dataMap.get("buyerid").toString() : null;
        String extparams = (dataMap.containsKey("extparams") && dataMap.get("extparams") != null)? dataMap.get("extparams").toString() : null;

        Result<PayResult> payResultResult = paymentBusinessFegin.paymentOrPaySms(tradenum,
                name,
                bankcardno,
                mobile,
                idcardno,
                expirydate,
                cvv2,
                authcode,
                openid,
                buyerid,
                userip,
                extparams);
        if (payResultResult.getStatus() == ResultStatusConstant.SUCCESS)
            return securityService.buildSybResult(payResultResult.getData(),requestData);
        else
            return new SybResult(-1,payResultResult.getMsg(),securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
    }




    public SybResult quickPaySmsConfirm(RequestData<String> requestData) {
        if (requestData.getEncryptType() != EncryptTypeConstant.AES)
            return new SybResult(-1, "加密方式不正确", securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        Map<String, Object> dataMap = securityService.getParametersMap(requestData);
        String accountid = requestData.getAccountid();
        String appcode = requestData.getAppcode();
        if (!dataMap.containsKey("tradenum") || dataMap.get("tradenum")==null )
            return new SybResult(-1,"缺少支付订单流水号",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        String tradenum = dataMap.get("tradenum").toString();
        if (!dataMap.containsKey("idcode") || dataMap.get("idcode")==null )
            return new SybResult(-1,"缺少短信验证码参数",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        String idcode = dataMap.get("idcode").toString();

        Result<PayResult> confirmResult = paymentBusinessFegin.quickPaySmsConfirm(tradenum,idcode);
        if (confirmResult.getStatus() == ResultStatusConstant.SUCCESS)
            return securityService.buildSybResult(confirmResult.getData(),requestData);
        else
            return new SybResult(-1,confirmResult.getMsg(),securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
    }


    public SybResult quickPayResendSms(RequestData<String> requestData) {
        if (requestData.getEncryptType() != EncryptTypeConstant.AES)
            return new SybResult(-1, "加密方式不正确", securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        Map<String, Object> dataMap = securityService.getParametersMap(requestData);
        String accountid = requestData.getAccountid();
        String appcode = requestData.getAppcode();
        if (!dataMap.containsKey("tradenum") || dataMap.get("tradenum")==null )
            return new SybResult(-1,"缺少支付订单流水号",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        String tradenum = dataMap.get("tradenum").toString();

        Result<PayResult> resendResult = paymentBusinessFegin.quickPayResendSms(tradenum);
        if (resendResult.getStatus() == ResultStatusConstant.SUCCESS)
            return securityService.buildSybResult(resendResult.getData(),requestData);
        else
            return new SybResult(-1,resendResult.getMsg(),securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
    }


    public SybResult paymentAssureConfirm(RequestData<String> requestData) {
        if (requestData.getEncryptType() != EncryptTypeConstant.AES)
            return new SybResult(-1, "加密方式不正确", securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        Map<String, Object> dataMap = securityService.getParametersMap(requestData);
        String accountid = requestData.getAccountid();
        String appcode = requestData.getAppcode();
        if (!dataMap.containsKey("tradenum") || dataMap.get("tradenum")==null )
            return new SybResult(-1,"缺少支付订单流水号",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        String tradenum = dataMap.get("tradenum").toString();

        ResultJson assureConfirmResult = paymentBusinessFegin.paymentAssureConfirm(tradenum);
        if (assureConfirmResult.getStatus() == ResultStatusConstant.SUCCESS)
            return securityService.buildSybResult(assureConfirmResult.getData(),requestData);
        else
            return new SybResult(-1,assureConfirmResult.getMsg(),securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
    }


    public SybResult paymentRefund(RequestData<String> requestData) {
        if (requestData.getEncryptType() != EncryptTypeConstant.AES)
            return new SybResult(-1, "加密方式不正确", securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        Map<String, Object> dataMap = securityService.getParametersMap(requestData);
        String accountid = requestData.getAccountid();
        String appcode = requestData.getAppcode();
        if (!dataMap.containsKey("tradenum") || dataMap.get("tradenum")==null )
            return new SybResult(-1,"缺少支付订单流水号",securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
        String tradenum = dataMap.get("tradenum").toString();

        ResultJson refundResult = paymentBusinessFegin.paymentRefund(tradenum);
        if (refundResult.getStatus() == ResultStatusConstant.SUCCESS)
            return securityService.buildSybResult(refundResult.getData(),requestData);
        else
            return new SybResult(-1,refundResult.getMsg(),securityService.sign(new SybResultData(requestData.getAccountid(),""),requestData.getAppcode()),requestData.getAccountid());
    }

}
